import { format } from "date-fns";
class RestDataProvider {
  constructor(url, updates) {
    this._url = url;
    this._queue = {};
    this._updates = updates;
    this._ids = new Map();
  }
  getData() {
    const tasksRequest = fetch(this._url + "/tasks").then((response) => response.json());
    const linksRequest = fetch(this._url + "/links").then((response) => response.json());
    return Promise.all([tasksRequest, linksRequest]).then(([tasks, links]) => ({ tasks, links }));
  }
  serializeTask(task) {
    return {
      progress: task.progress || 0,
      parent: task.parent ? this._ids.get("t" + task.parent) || task.parent : 0,
      text: task.text || "",
      details: task.details || "",
      type: task.type || "",
      duration: task.duration || 1,
      start_date: this.dateFormat(task.start_date),
      end_date: this.dateFormat(task.end_date),
    };
  }
  serializeMove(task) {
    return {
      mode: task.mode,
      target: task.target ? this._ids.get("t" + task.target) || task.target : 0,
      parent: task.parent ? this._ids.get("t" + task.parent) || task.parent : 0,
    };
  }
  serializeLink(link) {
    return {
      source: this._ids.get("t" + link.source) || link.source,
      target: this._ids.get("t" + link.target) || link.target,
      type: link.type,
    };
  }
  dateFormat(date) {
    return format(date, "yyyy-M-d") + " 00:00";
  }
  saveData(data) {
    const { action, obj } = data;
    let id = obj.id.toString();
    id = this._ids.get(action[action.lastIndexOf("-") + 1] + id) || id;
    switch (action) {
      case "update-task": {
        const timer = this._queue[id];
        timer && clearTimeout(timer),
        this._queue[id] = setTimeout(() => {
          this.send("/tasks/" + id, "PUT", this.serializeTask(obj))
        }, 1000 );
        break;
      }
      case "reorder-task":
        this.send(`/tasks/${id}/position`, "PUT", this.serializeMove(obj));
        break;
      case "add-task":
        this.send(
          "/tasks",
          "POST",
          Object.assign({ mode: data.mode }, this.serializeTask(obj))
        ).then((response) => {
          response.id && this._ids.set("t" + id, response.id.toString());
          this._updates && this._updates.task && this._updates.task(id, response);
        });
        break;
      case "delete-task":
        this.send("/tasks/" + id, "DELETE");
        break;
      case "update-link":
        this.send("/links/" + id, "PUT", this.serializeLink(obj));
        break;
      case "add-link":
        this.send("/links", "POST", this.serializeLink(obj)).then((response) => {
          response.id && this._ids.set("l" + id, response.id.toString());
          this._updates && this._updates.link && this._updates.link(id, response);
        });
        break;
      case "delete-link":
        this.send("/links/" + id, "DELETE");
    }
  }
  send(uri, method, body) {
    const config = {
      method,
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
    };
    if (body) {
      var line = [];
      for (var key in body) line.push(`${key}=${encodeURIComponent(body[key])}`);
  
      config.body = line.join("&");
    }
    return fetch(this._url + uri, config).then((response) => response.json());
  }
}
export { RestDataProvider };
